#include "PatchStomper/PatchStomperGUI.h"
#include "PatchStomper/StomperModel.h"
#include "PatchStomper/ToolElements/GridSplitter.h"
#include "PatchStomper/ToolElements/PatchInfoElement.h"
#include "PatchStomper/ToolElements/QuadAdder.h"
#include "PatchStomper/ToolElements/TextureInfoElement.h"
#include "PatchStomper/ToolElements/TextureTool.h"
#include "StompedReality/Core/FileSystem.h"
#include "StompedReality/Core/IGame.h"
#include "StomperLib/Elements/FileSelection.h"
#include <memory>
namespace PatchStomper {
PatchStomperGUI::PatchStomperGUI( Gwen::Controls::Canvas* canvas ) :
  StomperLib::BaseLayout( canvas )
{
  this->Model = new PatchStomper::StomperModel( this ); // this );
}

PatchStomperGUI::~PatchStomperGUI( )
{
}

void PatchStomperGUI::OnCreateBaseElements( )
{
  // Grid splitter
  auto splitter = new GridSplitter( this, this->m_Game, m_Camera );
  splitter->SetGame( this->m_Game );
  splitter->UpdateOrder = 4;
  splitter->DrawOrder = 1;
  this->AddToolElement( splitter );

  // Texture tool
  auto textureTool = new PatchStomper::TextureTool( this, this->m_Game, m_Camera );
  textureTool->UpdateOrder = 2;
  textureTool->DrawOrder = 0;
  this->AddToolElement( textureTool );

  // Quad adder
  auto quadAdder = new PatchStomper::QuadAdder( this, this->m_Game, m_Camera );
  quadAdder->UpdateOrder = 3;
  quadAdder->DrawOrder = 11;
  this->AddToolElement( quadAdder );

  // Patch Info
  auto patchElement = new PatchStomper::PatchInfoElement( this, this->m_Game, m_Camera );
  patchElement->UpdateOrder = 1;
  patchElement->DrawOrder = 30;
  this->AddToolElement( patchElement );

  // File tree
  auto fileSelection = new StomperLib::Elements::FileSelection( this, this->m_Game );
  fileSelection->SetGame( this->m_Game );

  // Texture info element
  auto textureInfoElement = new PatchStomper::TextureInfoElement( this, this->m_Game );

  // add events
  this->onOpenProject.Add( this, &PatchStomperGUI::OnOpenProject );
  this->onOpenProject.Add( this->Model, &StomperLib::ToolModel::OnOpenProject );
  this->onOpenProject.Add( fileSelection, &StomperLib::Elements::FileSelection::RefreshTree );

  fileSelection->onFileChanged.Add( textureInfoElement, &PatchStomper::TextureInfoElement::OnSelectFile );
  fileSelection->onFileChanged.Add( patchElement, &PatchStomper::PatchInfoElement::OnSelectFile );
  fileSelection->onFileChanged.Add( textureTool, &PatchStomper::TextureTool::OnOpenTexture );
  fileSelection->onFileChanged.Add( splitter, &PatchStomper::GridSplitter::OnTextureChange );

//  fileSelection->onFileAdded.Add( textureInfoElement, &PatchStomper::TextureInfoElement::OnAddFile );

  this->Model->onModified.Add( fileSelection, &StomperLib::Elements::FileSelection::OnModified );

  this->Model->onSaved.Add( fileSelection, &StomperLib::Elements::FileSelection::OnSaved );

  this->onSaveProject.Add( this, &PatchStomperGUI::SaveProject );
  this->onSaveProject.Add( patchElement,  &PatchStomper::PatchInfoElement::SaveCurrentPatcheFile );
  this->onSaveProject.Add( textureInfoElement, &PatchStomper::TextureInfoElement::SaveCurrentTextureInfo );
  this->onSaveProject.Add( this, &PatchStomperGUI::SaveProject );

  this->onSaveProject.Add( fileSelection, &StomperLib::Elements::FileSelection::OnSaved );
}

void PatchStomperGUI::OnOpenProject( Gwen::Event::Info info )
{
  int p = info.String.Get( ).find_last_of( FILE_SEPARATORE );
  this->m_Game->getFileSystem( )->setBasePath( info.String.Get( ).substr( 0, p ));
  this->Model->ProjectFile = info.String.Get( );
  auto patchModel = (PatchStomper::StomperModel*) this->Model;
  auto projectRoot = this->m_Game->getFileSystem( )->openAsJsonAbsolute( info.String.Get( ));
  patchModel->NextPatchID = projectRoot->get( "NextPatchID", 0 ).asUInt( );
  patchModel->NextTextureID = projectRoot->get( "NextTextureID", 0 ).asUInt( );
}

void PatchStomperGUI::SaveProject( )
{
  if (this->Model->ProjectFile.empty( ))
    return;

  auto patchModel = (PatchStomper::StomperModel*) this->Model;
  auto projectRoot = *(this->m_Game->getFileSystem( )->openAsJsonAbsolute( patchModel->ProjectFile ));

  projectRoot["NextPatchID"] = patchModel->NextPatchID;
  projectRoot["NextTextureID"] = patchModel->NextTextureID;

  this->m_Game->getFileSystem( )->saveJsonAbsolute( projectRoot, patchModel->ProjectFile );
}

}
